Mr.Lee-李健博的博客

[9-Gin路由高级]

2022-05-08

[9-Gin路由高级]

一 路由分组

routes group是为了管理一些相同的URL

https://gin-gonic.com/zh-cn/docs/examples/grouping-routes/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import (
"fmt"
"github.com/gin-gonic/gin"
)

// gin的helloWorld

func main() {
// 1.创建路由
r := gin.Default()
// 路由组1 ,处理GET请求
v1 := r.Group("/v1")
// {} 是书写规范,不写也可以
{
v1.GET("/login", login)
v1.GET("submit", submit) // /不写也可以
}
v2 := r.Group("/v2")

v2.POST("/login", login)
v2.POST("/submit", submit)

r.Run(":8000")
}

func login(c *gin.Context) {
name := c.DefaultQuery("name", "lqz")
c.String(200, fmt.Sprintf("hello %s\n", name))
}

func submit(c *gin.Context) {
name := c.DefaultQuery("name", "pyy")
c.String(200, fmt.Sprintf("hello %s\n", name))
}

测试

1
2
3
4
5
get请求:127.0.0.1:8000/v1/login
post请求:127.0.0.1:8000/v1/submit

get请求:127.0.0.1:8000/v2/login
post请求:127.0.0.1:8000/v2/submit

二 路由拆分与注册

2.1 基本路由注册

适用于路由比较少的简单项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main

import (
"net/http"

"github.com/gin-gonic/gin"
)

func helloHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Hello world!",
})
}

func main() {
r := gin.Default()
r.GET("/hello", helloHandler)
r.Run()
}

2.2 路由拆分成单独文件或包

当项目的规模增大后就不太适合继续在项目的main.go文件中去实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包

2.2.1 拆分到单独文件中(不使用分组)

目录结构

image-20200915230640851

routers.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)

func helloHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "www.liuqingzheng.top",
})
}
func testHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status":100,
"msg": "hello world",
})
}

func initRouter() *gin.Engine {
r := gin.Default()
r.GET("/hello", helloHandler)
r.GET("/test", testHandler)
return r
}

main.go

1
2
3
4
5
6
7
8
9
10
package main

func main() {
r := initRouter()
r.Run()
}

//访问
//http://127.0.0.1:8080/test
http://127.0.0.1:8080/hello

2.2.2 拆分到包中

目录结构

image-20200915231146634

routers/routers.go

routers/routers.go需要注意此时initRouter需要改成首字母大写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package routers
import (
"net/http"

"github.com/gin-gonic/gin"
)

func helloHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "www.liuqingzheng.top",
})
}
func testHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status":100,
"msg": "hello world",
})
}

func InitRouter() *gin.Engine {
r := gin.Default()
r.GET("/hello", helloHandler)
r.GET("/test", testHandler)
return r
}

main.go

1
2
3
4
5
6
7
8
package main

import "gin_test/routers"

func main() {
r := routers.InitRouter()
r.Run()
}

2.3 路由拆分成多个文件

单独的一个routers文件或包已经满足不了我们的需求了

目录结构

image-20200915232150667

routers/goods.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package routers

import (
"github.com/gin-gonic/gin"
"net/http"
)

func LoadGoodsRouters(r *gin.Engine) {
good := r.Group("/good")
{
good.GET("/", goodHandler)
good.GET("/goodlist", goodlistHandler)
good.GET("/updategood", updategoodHandler)
}
}
func goodHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "www.liuqingzheng.top",
})
}

func goodlistHandler(c *gin.Context) {
c.String(http.StatusOK, "goodlistHandler")
}
func updategoodHandler(c *gin.Context) {
c.String(http.StatusOK, "updategoodHandler")
}

routers/order.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package routers

import (
"github.com/gin-gonic/gin"
"net/http"
)

func LoadOrderRouters(r *gin.Engine) {
order := r.Group("/order")
{
order.GET("/", orderHandler)
order.GET("/orderlist", orderlistHandler)
order.GET("/updateorder", updateorderHandler)
}
}
func orderHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "www.liuqingzheng.top",
})
}

func orderlistHandler(c *gin.Context) {
c.String(http.StatusOK, "orderlistHandler")
}
func updateorderHandler(c *gin.Context) {
c.String(http.StatusOK, "updateorderHandler")
}

routers/user.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package routers

import (
"github.com/gin-gonic/gin"
"net/http"
)

func LoadUserRouters(r *gin.Engine) {
user := r.Group("/user")
{
user.GET("/", userHandler)
user.GET("/userlist", userlistHandler)
user.GET("/updateuser", updateuserHandler)
}
}
func userHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"msg": "www.liuqingzheng.top",
})
}

func userlistHandler(c *gin.Context) {
c.String(http.StatusOK, "userlistHandler")
}
func updateuserHandler(c *gin.Context) {
c.String(http.StatusOK, "updateuserHandler")
}

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import (
"gin_test/routers"
"github.com/gin-gonic/gin"
)

func main() {
r := gin.Default()
routers.LoadGoodsRouters(r)
routers.LoadOrderRouters(r)
routers.LoadUserRouters(r)
r.Run()
}

2.4 路由拆分到不同的APP

有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。

因此我们在项目目录下单独定义一个app目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。大致目录结构如下:

image-20200915233649087

app01/shop/handler.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package shop


import (
"github.com/gin-gonic/gin"
"net/http"
)

func shopHandler(c *gin.Context) {
c.String(http.StatusOK, "shopHandler")
}

func shopInfoHandler(c *gin.Context) {
c.String(http.StatusOK, "shopInfoHandler")
}

app01/shop/router.go

1
2
3
4
5
6
7
8
package shop

import "github.com/gin-gonic/gin"

func Routers(e *gin.Engine) {
e.GET("/shop", shopHandler)
e.GET("/shopinfo", shopInfoHandler)
}

app01/user/handler.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package user

import (
"github.com/gin-gonic/gin"
"net/http"
)

func userHandler(c *gin.Context) {
c.String(http.StatusOK, "userHandler")
}

func userInfoHandler(c *gin.Context) {
c.String(http.StatusOK, "userInfoHandler")
}

app01/user/router.go

1
2
3
4
5
6
7
8
9
package user


import "github.com/gin-gonic/gin"

func Routers(e *gin.Engine) {
e.GET("/user", userHandler)
e.GET("/userinfo", userInfoHandler)
}

routers/routers.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package routers

import "github.com/gin-gonic/gin"

type Option func(engine *gin.Engine)
var options=[]Option{}
//注册app的路由配置
func Include(opts ...Option) {
options=append(options,opts...)
}
//初始化
func Init()*gin.Engine {
r:=gin.New()
for _,opt:=range options{
opt(r)
}
return r
}

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"gin_test/app01/shop"
"gin_test/app01/user"
"gin_test/routers"
)

func main() {
routers.Include(shop.Routers,user.Routers)
r:=routers.Init()
r.Run()
}
使用支付宝打赏
使用微信打赏

点击上方按钮,请我喝杯咖啡!

扫描二维码,分享此文章